package packageDataAccess;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import javax.sql.DataSource;
import javax.naming.InitialContext;
import javax.naming.Context;
import javax.naming.NamingException;
import packageException.CommandeException;
import packageException.DataException;
import packageModel.Commande;

/**
 *
 * @author Lionel & Julien
 * 
 */
public class CommandeSyllathequeData {
    /**
     * Récupère la dernière commande afin de pouvoir calculer un nouvel id pour une prochaine commande
     * 
     * @return numCde
     * @throws CommandeException
     * @throws DataException  
     */
    public int lastNumCde() throws 
            CommandeException,
            DataException {
        int lastNumCde = -1;
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext(); 
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque"); 
            Connection connexion = source.getConnection();
            
            // SQL
            String requeteSql = "SELECT MAX(numCde) FROM Commande";

            // Traitement
            PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
            
            ResultSet donnees = prepStat.executeQuery();
            donnees.next();
            
            lastNumCde = donnees.getInt(1);
            lastNumCde++;
            
            // Fermeture de la connexion
            connexion.close();
        } catch(SQLException e) {
            // ERREUR
            throw new CommandeException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        return lastNumCde;
    }
    
    /**
     * Insertion d'une nouvelle commande
     * 
     * @param pseudo
     * @param dateCommande
     * @param dateCloture
     * @param isCloturee
     * @return Commande
     * @throws CommandeException
     * @throws DataException  
     */
    public Commande insertCommande(String pseudo, GregorianCalendar dateCommande, GregorianCalendar dateCloture, Boolean isCloturee) throws 
            CommandeException,
            DataException {
        Commande cde = null;
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext(); 
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque"); 
            Connection connexion = source.getConnection();

            int lastNumCde = this.lastNumCde();
            
            // SQL
            String requeteSql = "INSERT INTO "
                    + "Commande(numCde, pseudo, dateCommande, isCloturee) "
                    + "VALUES(?, ?, ?, ?)";

            // Traitement
            java.sql.Date dateCde = new java.sql.Date(dateCommande.getTimeInMillis());
            int isClot = 0;
            if(isCloturee == true)
                isClot = 1;
            
            PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
            prepStat.setInt(1, lastNumCde);
            prepStat.setString(2, pseudo);
            prepStat.setDate(3, dateCde);
            prepStat.setInt(4, isClot);
            
            prepStat.executeUpdate();
            
            cde = new Commande(
                            lastNumCde, 
                            pseudo, 
                            dateCommande, 
                            isCloturee
                        );
            
            // A-t-on une date de livraison ? Si oui, on l'ajoute à notre commande !
            if(dateCloture != null) {
                java.sql.Date dateClot = new java.sql.Date(dateCloture.getTimeInMillis());

                requeteSql = "UPDATE Commande "
                        + "SET dateCloture = ? "
                        + "WHERE numCde = ?";
                
                prepStat.setDate(1, dateClot);
                prepStat.setInt(2, lastNumCde);
                prepStat.executeUpdate();
                
                cde.setDateCloture(dateCloture);
            }
            
            // Fermeture de la connexion
            connexion.close();
        }
        catch(SQLException e) {
            // ERREUR
            throw new CommandeException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        return cde;
    }

    
    
    /**
     * Récupère la commande dont l'id est passé en argument
     * 
     * @param numCde
     * @return Commande
     * @throws CommandeException
     * @throws DataException  
     */
    public Commande getCommandeByCde(int numCde) throws 
            CommandeException,
            DataException {
        Commande cde = null;
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext(); 
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque"); 
            Connection connexion = source.getConnection();
            
            // SQL
            String requeteSql = "SELECT * "
                    + "FROM Commande "
                    + "WHERE numCde = ?";

            // Traitement
            PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
            prepStat.setInt(1, numCde);

            ResultSet donnees = prepStat.executeQuery();
            donnees.next();
            
            // Date
            java.sql.Date dateCommande = donnees.getDate("dateCommande");
            GregorianCalendar gd = new GregorianCalendar();
            gd.setTime(dateCommande);

            // Notre commande est-elle clôturée ?
            Boolean isCloturee = null;
            if(donnees.getInt("isCloturee") == 0)
                isCloturee = false;
            else
                isCloturee = true;
            
            cde = new Commande(
                    donnees.getInt("numCde"), 
                    donnees.getString("pseudo"), 
                    gd,
                    isCloturee
                  );

            // A-t-on une date de livraison ?
            if(donnees.getDate("dateCloture") != null) {
                java.sql.Date dateCloture = donnees.getDate("dateCloture");
                GregorianCalendar gl = new GregorianCalendar();
                gl.setTime(dateCloture);

                cde.setDateCloture(gl);
            }
            
            // Fermeture de la connexion
            connexion.close();
        }
        catch(SQLException e) {
            // ERREUR
            throw new CommandeException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        return cde;
    }
    
    /**
     * Récupère la dernière commande de l'utilisateur dont le pseudo est passé en paramètre
     * 
     * @param pseudo
     * @return Commande
     * @throws CommandeException
     * @throws DataException  
     */
    public Commande lastCommande(String pseudo) throws 
            CommandeException,
            DataException {
        Commande cde = null;
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext(); 
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque"); 
            Connection connexion = source.getConnection();
            
            // SQL
            String requeteSql = "SELECT * "
                    + "FROM Commande "
                    + "WHERE pseudo = ? AND isCloturee = 0";
            
            // Traitement
            PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
            prepStat.setString(1, pseudo);
            prepStat.setMaxRows(1);

            ResultSet donnees = prepStat.executeQuery();
            donnees.next();
            
            // Date
            java.sql.Date dateCommande = donnees.getDate("dateCommande");
            GregorianCalendar gd = new GregorianCalendar();
            gd.setTime(dateCommande);

            // Notre commande est-elle clôturée ?
            Boolean isCloturee = null;
            if(donnees.getInt("isCloturee") == 0)
                isCloturee = false;
            else
                isCloturee = true;
            

            cde = new Commande(
                            donnees.getInt("numCde"), 
                            donnees.getString("pseudo"), 
                            gd,
                            isCloturee
                        );

            // A-t-on une date de clôture ?
            if(donnees.getDate("dateCloture") != null) {
                java.sql.Date dateCloture = donnees.getDate("dateCloture");
                GregorianCalendar gl = new GregorianCalendar();
                gl.setTime(dateCloture);

                cde.setDateCloture(gl);
            }
            
            // Fermeture
            connexion.close();
        }
        catch(SQLException e) {
            // ERREUR
            throw new CommandeException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        return cde;
    }
    
    
    
    /**
     * Récupère le nombre de commande de l'utilisateur dont le pseudo est passé en argument
     * Il y en aura au maximum une !
     * 
     * @param pseudo
     * @return nbCde
     * @throws CommandeException
     * @throws DataException  
     */
    public int getNbCommande(String pseudo) throws 
            CommandeException,
            DataException {
        int nbCde = 0;
        try {
            // Connexion à la base de données
            Context ctx = new InitialContext(); 
            DataSource source = (DataSource) ctx.lookup("jdbc/Syllatheque"); 
            Connection connexion = source.getConnection();
            
            // SQL
            String requeteSql = "SELECT * "
                    + "FROM Commande "
                    + "WHERE pseudo = ? AND isCloturee = 0";

            // Traitement
            PreparedStatement prepStat = connexion.prepareStatement(requeteSql);
            prepStat.setString(1, pseudo);
            prepStat.setMaxRows(1);

            ResultSet donnees = prepStat.executeQuery();
            donnees.next();
            
            nbCde = donnees.getRow();
            
            // Fermeture de la connexion
            connexion.close();
        }
        catch(SQLException e) {
            // ERREUR
            throw new CommandeException(e.getMessage());
        }
        catch(NamingException e) {
            // ERREUR
            throw new DataException(e.getMessage());
        }
        return nbCde;
    }
}
